package com.internetCafes.spms.web.customer.common.handler;

import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.core.exception.RRExceptionCodeEnum;
import com.internetCafes.spms.web.customer.common.cont.CommonConst;
import com.internetCafes.spms.web.customer.common.cont.CustomerConst;
import com.internetCafes.spms.web.customer.common.cont.UserConst;
import com.internetCafes.spms.web.customer.common.util.UserInfoUtil;
import com.internetCafes.spms.web.customer.model.customer.CustomerTransferUserTreeReq;
import com.internetCafes.spms.web.customer.model.customer.CustomerTransferUserTreeRes;
import com.internetCafes.spms.web.customer.model.user.EntUserEmployeeInfoListPo;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.sms.common.util.hutool.core.collection.CollectionUtil;
import com.sms.common.util.hutool.core.util.ObjectUtil;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 用户处理器
 */
public class TransferUserTreeHandler {

    private static TransferUserTreeHandler instance;

    private TransferUserTreeHandler() {

    }

    public static TransferUserTreeHandler getInstance() {
        if (ObjectUtil.isNull(instance)) {
            instance = new TransferUserTreeHandler();
        }
        return instance;
    }

    public void clearNullUserNode(List<CustomerTransferUserTreeRes> deptTreeList) {
        Iterator<CustomerTransferUserTreeRes> iterator = deptTreeList.iterator();
        while (iterator.hasNext()) {
            CustomerTransferUserTreeRes next = iterator.next();
            if (!hasChildrenUser(next)) {
                iterator.remove();
                continue;
            }
            if (CollectionUtil.isNotEmpty(next.getChildren())) {
                clearNullUserNode(next.getChildren());
            }
        }
    }

    public boolean hasChildrenUser(CustomerTransferUserTreeRes node) {
        if (CollectionUtil.isEmpty(node.getChildren()) && CollectionUtil.isEmpty(node.getUserList())) {
            return false;
        }
        if (CollectionUtil.isNotEmpty(node.getUserList())) {
            return true;
        }
        for (CustomerTransferUserTreeRes child : node.getChildren()) {
            boolean result = hasChildrenUser(child);
            if (result) {
                return true;
            }
        }
        return false;
    }

    public void deptUserAdd(List<CustomerTransferUserTreeRes> deptTreeeList, Map<Long, List<CustomerTransferUserTreeRes.User>> userDataMapByDeptId, Map<Long, List<CustomerTransferUserTreeRes.User>> userMapByDeptId) {
        for (CustomerTransferUserTreeRes treeNode : deptTreeeList) {
            if (CollectionUtil.isNotEmpty(treeNode.getChildren())) {
                deptUserAdd(treeNode.getChildren(), userDataMapByDeptId, userMapByDeptId);
            }
            if (userDataMapByDeptId.containsKey(treeNode.getId())) {
                treeNode.setUserList(userDataMapByDeptId.get(treeNode.getId()));
                userDataMapByDeptId.remove(treeNode.getId());
                continue;
            }
            if (userMapByDeptId.containsKey(treeNode.getId())) {
                treeNode.setUserList(userMapByDeptId.get(treeNode.getId()));
                userDataMapByDeptId.remove(treeNode.getId());
            }
        }
    }

    public void treeNodeInfoAdd(List<CustomerTransferUserTreeRes> deptTreeList, Map<Long, CustomerTransferUserTreeRes> treeNodeMapById) {
        for (CustomerTransferUserTreeRes customerTransferUserTreeRes : deptTreeList) {
            if (treeNodeMapById.containsKey(customerTransferUserTreeRes.getId())) {
                customerTransferUserTreeRes.setChildren(treeNodeMapById.get(customerTransferUserTreeRes.getId()).getChildren());
            }
            if (CollectionUtil.isNotEmpty(customerTransferUserTreeRes.getChildren())) {
                treeNodeInfoAdd(customerTransferUserTreeRes.getChildren(), treeNodeMapById);
            }
        }
    }

    /**
     * 整个树型结构
     *
     * @param deptList 部门列表
     * @return 树型数据
     */
    public List<CustomerTransferUserTreeRes> totalDeptTree(List<CustomerTransferUserTreeRes> deptList) {
        List<Long> deptIdList = deptList.stream().map(CustomerTransferUserTreeRes::getId).collect(Collectors.toList());
        List<CustomerTransferUserTreeRes> rootDeptList = deptList.stream().filter(deptTemp -> !deptIdList.contains(deptTemp.getParentId())).collect(Collectors.toList());
        deptInfoTreeDown(rootDeptList, deptList);
        return rootDeptList;
    }


    /**
     * 拆分为list
     *
     * @param deptTreeList 根列表
     * @return 节点列表
     */
    public List<CustomerTransferUserTreeRes> deptTreeSplit(List<CustomerTransferUserTreeRes> deptTreeList) {
        List<CustomerTransferUserTreeRes> resultList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(deptTreeList)) {
            for (CustomerTransferUserTreeRes node : deptTreeList) {
                resultList.add(node);
                if (CollectionUtil.isNotEmpty(node.getChildren())) {
                    resultList.addAll(deptTreeSplit(node.getChildren()));
                }
            }
        }
        return resultList;
    }

    /**
     * 处理两个列表中部门树型问题
     *
     * @param deptList     部门列表
     * @param deptDataList 授权部门列表
     * @return 部门列表
     */
    public List<CustomerTransferUserTreeRes> deptTreeListMerge(List<CustomerTransferUserTreeRes> deptList, List<CustomerTransferUserTreeRes> deptDataList) {
        List<Long> deptIdList = getDeptIdList(deptList);
        List<Long> deptDataIdList = getDeptIdList(deptDataList);
        // 获取交集idList
        List<Long> intersectionIdList = deptIdList.stream()
                .filter(deptDataIdList::contains)
                .collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(intersectionIdList)) {
            // 获取dept中不包含deptData得部分
            List<Long> differenceDeptIdList = deptIdList.stream()
                    .filter(deptId -> !deptDataIdList.contains(deptId))
                    .collect(Collectors.toList());
            if (CollectionUtil.isEmpty(differenceDeptIdList)) {
                return deptDataList;
            }
            // 获取deptData中不包含dept得部分
            List<Long> differenceDeptDataIdList = deptDataIdList.stream()
                    .filter(deptDataId -> !deptIdList.contains(deptDataId))
                    .collect(Collectors.toList());
            if (CollectionUtil.isEmpty(differenceDeptDataIdList)) {
                return deptList;
            }
            return deptDataList;
        }
        deptDataList.addAll(deptList);
        return deptDataList;
    }

    /**
     * 获取部门id列表
     *
     * @param deptList 部门列表
     * @return 部门id列表
     */
    public List<Long> getDeptIdList(List<CustomerTransferUserTreeRes> deptList) {
        List<Long> deptIdList = deptList.stream().map(CustomerTransferUserTreeRes::getId)
                .collect(Collectors.toList());

        for (CustomerTransferUserTreeRes deptTemp : deptList) {
            if (CollectionUtil.isNotEmpty(deptTemp.getChildren())) {
                deptIdList.addAll(getDeptIdList(deptTemp.getChildren()));
            }
        }

        return deptIdList;
    }

    /**
     * 授权部门树型
     *
     * @param deptList 部门列表
     * @param userList 用户列表
     * @return 授权部门列表
     */
    public List<CustomerTransferUserTreeRes> deptDataTree(List<CustomerTransferUserTreeRes> deptList, List<CustomerTransferUserTreeRes.User> userList) {
        List<Long> deptIdList = deptList
                .stream()
                .map(CustomerTransferUserTreeRes::getId)
                .collect(Collectors.toList());
        // 筛选部门列表中
        List<CustomerTransferUserTreeRes> startDeptList = deptList.stream()
                .filter(deptPo -> !deptIdList.contains(deptPo.getParentId()))
                .collect(Collectors.toList());
        Map<Long, List<CustomerTransferUserTreeRes.User>> userGroupByDeptId = userList.stream()
                .collect(Collectors.groupingBy(CustomerTransferUserTreeRes.User::getDeptId));
        deptInfoTreeDown(startDeptList, deptList, userGroupByDeptId);
        return startDeptList;
    }

    /**
     * 人员部门树形数据处理
     *
     * @param req      请求参数
     * @param deptList 部门信息列表
     * @param userList 人员列表
     * @param user     当前用户信息
     * @return 人员树形数据列表
     */
    public List<CustomerTransferUserTreeRes> customerTransferUserTree(CustomerTransferUserTreeReq req, List<CustomerTransferUserTreeRes> deptList, List<CustomerTransferUserTreeRes.User> userList, UserInfo user) {
        /*
         * 一、筛选
         *      1-管理员 manager_flag null . 展示所有人列表
         *      2-地区管理员，展示对应部门数据人员
         * 二、转让规则
         *      管理层，能够进行转让
         *      销售，转让只支持向上管理层转让
         */
        // 获取当前用户
        // EntUserEmployeeInfoListPo userPo = getUserEmployeeInfoPo(userEmployeeInfoPoList, user);

        if (ObjectUtil.isNull(userList)) {
            return new ArrayList<>();
        }

        List<CustomerTransferUserTreeRes> startDeptList;

        // 获取当前用户的部门 - 企业内人员
        if (UserInfoUtil.entSuperAdminJudge(user)) {
            // 获取根节点部门列表
            startDeptList = deptList.stream()
                    .filter(po -> UserConst.DEPT_ROOT_PARENT.equals(po.getParentId()))
                    .collect(Collectors.toList());
        } else {
            Map<Long, CustomerTransferUserTreeRes> deptMapById = deptList.stream()
                    .collect(Collectors.toMap(CustomerTransferUserTreeRes::getId, Function.identity()));
            if (!deptMapById.containsKey(user.getTenantDeptId())) {
                return new ArrayList<>();
            }
            CustomerTransferUserTreeRes tenantDeptInfo = deptMapById.get(user.getTenantDeptId());
            startDeptList = Collections.singletonList(tenantDeptInfo);
        }

        if (CustomerConst.TransferUserTreeAction.CUSTOMER_TRANSFER.getId().equals(req.getActionId())) {
            return userTreeForTransfer(startDeptList, deptList, userList, user);
        }
        if (CustomerConst.TransferUserTreeAction.CUSTOMER_SEARCH.getId().equals(req.getActionId())) {
            // 非管理人只有自己得部门信息
            if (!UserInfoUtil.managerJudge(user)) {
                userList = userList.stream()
                        .filter(userPo -> user.getId().equals(userPo.getId()))
                        .collect(Collectors.toList());
                List<CustomerTransferUserTreeRes.User> userListRes;
                for (CustomerTransferUserTreeRes customerTransferUserTreeRes : startDeptList) {
                    userListRes = new ArrayList<>();
                    for (CustomerTransferUserTreeRes.User userTemp : userList) {
                        if (customerTransferUserTreeRes.getId().equals(userTemp.getDeptId())) {
                            userListRes.add(userTemp);
                        }
                    }
                    customerTransferUserTreeRes.setUserList(userListRes);
                }
                return startDeptList;
            }
            return userTreeForSearch(startDeptList, deptList, userList);
        }

        throw new RRException(RRExceptionCodeEnum.PARAM_ERROR);
    }

    /**
     * 客户筛选
     *
     * @param deptInfoPoList         部门列表
     * @param userEmployeeInfoPoList 用户员工列表
     * @return 结果树
     */
    private List<CustomerTransferUserTreeRes> userTreeForSearch(List<CustomerTransferUserTreeRes> startNodeList, List<CustomerTransferUserTreeRes> deptInfoPoList, List<CustomerTransferUserTreeRes.User> userEmployeeInfoPoList) {

        Map<Long, List<CustomerTransferUserTreeRes.User>> userEmployeeInfoList = userEmployeeInfoPoList.stream()
                .collect(Collectors.groupingBy(CustomerTransferUserTreeRes.User::getDeptId));

        deptInfoTreeDown(startNodeList, deptInfoPoList, userEmployeeInfoList);

        return startNodeList;
    }

    /**
     * 从用户中获取当前用户信息
     *
     * @param userEmployeeInfoPoList 用户列表
     * @param user                   当前用户信息
     * @return 当前用户带员工信息
     */
    private EntUserEmployeeInfoListPo getUserEmployeeInfoPo(List<EntUserEmployeeInfoListPo> userEmployeeInfoPoList, UserInfo user) {
        return CollectionUtil.getFirst(userEmployeeInfoPoList.stream()
                .filter(po -> user.getId().equals(po.getId()))
                .collect(Collectors.toList()));
    }

    /**
     * 客户转让 获取客户树形数据
     *
     * @param deptInfoPoList         部门列表
     * @param userEmployeeInfoPoList 用户员工列表
     * @param userPo                 当前用户信息
     * @return 结果树
     */
    private List<CustomerTransferUserTreeRes> userTreeForTransfer(List<CustomerTransferUserTreeRes> startNodeList, List<CustomerTransferUserTreeRes> deptInfoPoList, List<CustomerTransferUserTreeRes.User> userEmployeeInfoPoList, UserInfo userPo) {
        Map<Long, List<CustomerTransferUserTreeRes.User>> userGroupByDeptId = userEmployeeInfoPoList.stream()
                .filter(po -> {
                    if (UserInfoUtil.entSuperAdminJudge(userPo) || UserInfoUtil.managerJudge(userPo)) {
                        return true;
                    }
                    return !userPo.getId().equals(po.getId());
                })
                .collect(Collectors.groupingBy(CustomerTransferUserTreeRes.User::getDeptId));
        // 超级管理员用户 获取全部列表
        if (ObjectUtil.isNull(userPo.getManagerFlag())) {

            deptInfoTreeDown(startNodeList, deptInfoPoList, userGroupByDeptId);

        } else if (CommonConst.FlagEnum.IS.getId().equals(userPo.getManagerFlag())) {
            Map<Long, CustomerTransferUserTreeRes> deptMapById = deptInfoPoList.stream()
                    .collect(Collectors.toMap(CustomerTransferUserTreeRes::getId, Function.identity()));
            // 管理员用户 向上向下
            // 获取当前用户的部门
            CustomerTransferUserTreeRes rootDept = CollectionUtil.getFirst(deptInfoPoList.stream().filter(deptPo -> deptPo.getId().equals(userPo.getTenantDeptId())).collect(Collectors.toList()));
            if (ObjectUtil.isNull(rootDept)) {
                return new ArrayList<>();
            }
            deptInfoTreeDown(startNodeList, deptInfoPoList, userGroupByDeptId);
            // 从部门开始向上走
            startNodeList = Collections.singletonList(deptInfoTreeUp(CollectionUtil.getFirst(startNodeList), deptMapById, userGroupByDeptId));
        } else {

            // 从部门开始向上走
            Map<Long, CustomerTransferUserTreeRes> deptMapById = deptInfoPoList.stream()
                    .collect(Collectors.toMap(CustomerTransferUserTreeRes::getId, Function.identity()));

            // 人员分组 去除非管理人员信息
            userGroupByDeptId = userEmployeeInfoPoList.stream()
                    .filter(po -> !CommonConst.FlagEnum.NOT.getId().equals(po.getManagerFlag()))
                    .collect(Collectors.groupingBy(CustomerTransferUserTreeRes.User::getDeptId));

            CustomerTransferUserTreeRes startDept = deptMapById.get(userPo.getTenantDeptId());

            startNodeList = Collections.singletonList(deptInfoTreeUp(startDept, deptMapById, userGroupByDeptId));
        }
        return startNodeList;
    }

    /**
     * 从子节点向上封装树状数据
     *
     * @param startNode         开始节点
     * @param deptMapById       部门分组
     * @param userGroupByDeptId 用户分组通过部门id
     * @return 部门列表信息
     */
    private CustomerTransferUserTreeRes deptInfoTreeUp(CustomerTransferUserTreeRes startNode, Map<Long, CustomerTransferUserTreeRes> deptMapById, Map<Long, List<CustomerTransferUserTreeRes.User>> userGroupByDeptId) {
        // 部门人员 封装
        if (userGroupByDeptId.containsKey(startNode.getId())) {
            startNode.setUserList(userGroupByDeptId.get(startNode.getId()));
        }

        // 查找父部门
        if (!UserConst.DEPT_ROOT_PARENT.equals(startNode.getParentId())
                && ObjectUtil.isNotNull(startNode.getParentId()) && deptMapById.containsKey(startNode.getParentId())) {
            CustomerTransferUserTreeRes parentDept = deptMapById.get(startNode.getParentId());
            parentDept.setChildren(Collections.singletonList(startNode));
            startNode = deptInfoTreeUp(parentDept, deptMapById, userGroupByDeptId);
        }
        return startNode;
    }

    private void setLastChildren(CustomerTransferUserTreeRes parentInfo, CustomerTransferUserTreeRes childRes) {
        if (CollectionUtil.isNotEmpty(parentInfo.getChildren())) {
            setLastChildren(CollectionUtil.getFirst(parentInfo.getChildren()), childRes);
        } else {
            parentInfo.setChildren(Collections.singletonList(childRes));
        }
    }

    /**
     * 向下 - 封装部门人员树形数据
     *
     * @param startDeptList     开始部门列表
     * @param deptInfoPoList    部门全部列表
     * @param userGroupByDeptId 人员列表分组通过部门id
     */
    private void deptInfoTreeDown(List<CustomerTransferUserTreeRes> startDeptList, List<CustomerTransferUserTreeRes> deptInfoPoList, Map<Long, List<CustomerTransferUserTreeRes.User>> userGroupByDeptId) {
        List<Long> startDeptIdList = startDeptList.stream().map(CustomerTransferUserTreeRes::getId).collect(Collectors.toList());
        // 获取子部门列表
        List<CustomerTransferUserTreeRes> children
                = deptInfoPoList.stream()
                .filter(dept -> startDeptIdList.contains(dept.getParentId()))
                .collect(Collectors.toList());
        Map<Long, List<CustomerTransferUserTreeRes>> childrenGroupByParentId = new HashMap<>();

        if (CollectionUtil.isNotEmpty(children)) {
            deptInfoTreeDown(children, deptInfoPoList, userGroupByDeptId);
            childrenGroupByParentId = children.stream()
                    .collect(Collectors.groupingBy(CustomerTransferUserTreeRes::getParentId));
        }
        // 封装数据
        for (CustomerTransferUserTreeRes startDept : startDeptList) {
            if (userGroupByDeptId.containsKey(startDept.getId())) {
                startDept.setUserList(userGroupByDeptId.get(startDept.getId()));
            }
            if (childrenGroupByParentId.containsKey(startDept.getId())) {
                startDept.setChildren(childrenGroupByParentId.get(startDept.getId()));
            }
        }
    }

    /***
     * 向下遍历部门信息
     * @param startDeptList 起始部门信息
     * @param deptInfoPoList 部门信息列表
     */
    private void deptInfoTreeDown(List<CustomerTransferUserTreeRes> startDeptList, List<CustomerTransferUserTreeRes> deptInfoPoList) {
        List<Long> startDeptIdList = startDeptList.stream().map(CustomerTransferUserTreeRes::getId).collect(Collectors.toList());
        // 获取子部门列表
        List<CustomerTransferUserTreeRes> children
                = deptInfoPoList.stream()
                .filter(dept -> startDeptIdList.contains(dept.getParentId()))
                .collect(Collectors.toList());
        Map<Long, List<CustomerTransferUserTreeRes>> childrenGroupByParentId = new HashMap<>();

        if (CollectionUtil.isNotEmpty(children)) {
            deptInfoTreeDown(children, deptInfoPoList);
            childrenGroupByParentId = children.stream()
                    .collect(Collectors.groupingBy(CustomerTransferUserTreeRes::getParentId));
        }
        // 封装数据
        for (CustomerTransferUserTreeRes startDept : startDeptList) {
            if (childrenGroupByParentId.containsKey(startDept.getId())) {
                startDept.setChildren(childrenGroupByParentId.get(startDept.getId()));
            }
        }
    }
}
